using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using NUnit.Framework;
using ODX.Core;
using ODX.LazyUnitTester;

namespace Persistence
{
    [Table]
    public abstract class Person : Entity
    {
        public abstract string Name { get; set;}
        public abstract DateTime DateOfBirth { get; set;}
        public int Age { get { return (int) ((DateTime.Now - DateOfBirth).Days/365.25); } }

        public abstract IEntityList<Pet> Pets { get; }
    }

    [Table()]
    public abstract class Pet : Entity
    {
        public abstract string Name { get; set;}
        public abstract Person Master { get; set; }
    }

    [TestFixture]
    public class C04_Persistence
    {
        [TestBody]
        static void Main()
        {
            const string filename = "pets.xml";
            if (File.Exists(filename))
                File.Delete(filename);

            Session session = new Session(new XmlDataProvider(filename));
            session.RegisterAssembly(Assembly.GetExecutingAssembly());
            session.Prepare();

            Person john = session.Create<Person>();
            john.Name = "John";

            Pet cat = session.Create<Pet>();
            cat.Name = "Molly";
            Pet dog = session.Create<Pet>();
            dog.Name = "Beethoven";

            john.Pets.Add(cat, dog);

            session.Save();

            Session reader = session.Clone();

            List<Person> humans = new List<Person>(reader.All<Person>());
            humans.Sort(CompareHumans);
            foreach (Person h in humans)
            {
                LUT.WriteLine("{0} masters the following pets:", h.Name);
                foreach ( Pet p in h.Pets )
                    LUT.WriteLine("\t{0}", p.Name);
            }
        }

        private static int CompareHumans(Person x, Person y)
        {
            return x.Name.CompareTo(y.Name);
        }

        [Test]
        public void Test()
        {
            LUT.Execute(Main);
        }
    }
}
